﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using CCodeTreeLib;
using SqlOrm.TreeBuilders;
using SqlOrm.Xml;
using System.IO;
using SqlOrm.ScriptBuilder;
using System.Diagnostics;

namespace SqlOrm
{
    class Program
    {
        [STAThread]
        static void Main(string[] args)
        {
            var arguments = new Args(args);
            Console.WriteLine("SqlData Generator 1.0");
            string file=null;
            string exepath = Directory.GetCurrentDirectory();
            string xmlpath = "";
            file = arguments["conf"];
            if (arguments["dbg"] != null)
                Debugger.Launch();
            if (string.IsNullOrEmpty(file))
            {
                var ofd = new OpenFileDialog();
                ofd.Title = "Database Definition file";
                ofd.RestoreDirectory = true;
                if (ofd.ShowDialog() == DialogResult.OK)
                    file = ofd.FileName;
                else
                    return;
            }

            if (!string.IsNullOrEmpty(file))
            {
                file = CombinePath(exepath, file);
                if (File.Exists(file))
                {
                    xmlpath = Path.GetDirectoryName(file);

                    string xml = File.ReadAllText(file);
                    var ddl = Serializer.DeSerialize<DataDictionary>(xml);
                    if (!string.IsNullOrEmpty(ddl.Settings.Database.conn))
                    {
                        var parser = new SqlDDLParser(ddl.Settings.Database.conn, (ddl.Settings.Database.ver == DatabaseVersion.SqlCompact35));
                        parser.CreateTables(ddl);
                        parser.CreateProcs(ddl);
                    }
                    ddl.SupressModel();

                    if (ddl.Settings.ScriptOutput != null)
                    {
                        var sb = new ScriptBuilderFactory(xmlpath,ddl);
                        sb.Build();
                    }

                    if (ddl.Settings.DDLOutput != null)
                    {
                        //var fields = ddl.Definition.Schema.Table.SelectMany(x => x.Field);

                        string ddlpath = ddl.Settings.DDLOutput.path;
                        ddl.Settings.DDLOutput = null;
                        ddl.Settings.Database.conn = null;
                        if (File.Exists(CombinePath(xmlpath, ddlpath)))
                            File.Delete(CombinePath(xmlpath, ddlpath));
                        File.AppendAllText(CombinePath(xmlpath, ddlpath), Serializer.Serialize(ddl));
                    }

                    CodeTreeCSharpProvider cs = new CodeTreeCSharpProvider();

                    if (ddl.Settings.EntitiesOutput != null)
                    {
                        var swe = new StreamWriter(CombinePath(xmlpath, ddl.Settings.EntitiesOutput.pathname));
                        cs.Dump(new EntitiesTreeBuilder(ddl), swe.BaseStream);
                        swe.Close();
                        swe.Dispose();
                    }

                    if (ddl.Settings.UIEntitiesOutput != null)
                    {
                        var swe = new StreamWriter(CombinePath(xmlpath, ddl.Settings.UIEntitiesOutput.pathname));
                        cs.Dump(new UIEntitiesTreeBuilder(ddl), swe.BaseStream);
                        swe.Close();
                        swe.Dispose();
                    }

                    SqlContextTreeBuilder sqlcontext = null;
                    if (ddl.Settings.ContextOutput != null)
                        sqlcontext = new SqlContextTreeBuilder(ddl);

                    if (ddl.Settings.ContextOutput != null)
                    {
                        var sws = new StreamWriter(CombinePath(xmlpath, ddl.Settings.ContextOutput.pathname));
                        cs.Dump(sqlcontext, sws.BaseStream);
                        sws.Close();
                        sws.Dispose();
                    }

                    if (ddl.Settings.DataContractOutput != null)
                    {
                        var swdc = new StreamWriter(CombinePath(xmlpath, ddl.Settings.DataContractOutput.pathname));
                        cs.Dump(new DataContractTreeBuilder(ddl), swdc.BaseStream);
                        swdc.Close();
                        swdc.Dispose();
                    }

                    if (ddl.Settings.BusinessOutput != null)
                    {
                        var swbc = new StreamWriter(CombinePath(xmlpath, ddl.Settings.BusinessOutput.pathname));
                        cs.Dump(new ServiceBusinessLogicTreeBuilder(ddl, sqlcontext), swbc.BaseStream);
                        swbc.Close();
                        swbc.Dispose();
                    }

                    if (ddl.Settings.ServiceContractOutput != null)
                    {
                        var swsc = new StreamWriter(CombinePath(xmlpath, ddl.Settings.ServiceContractOutput.pathname));
                        cs.Dump(new ServiceContractTreeBuilder(ddl, sqlcontext), swsc.BaseStream);
                        swsc.Close();
                        swsc.Dispose();
                    }

                    if (ddl.Settings.ServiceImplOutput != null)
                    {
                        var swsi = new StreamWriter(CombinePath(xmlpath, ddl.Settings.ServiceImplOutput.pathname));
                        cs.Dump(new ServiceImplementationTreeBuilder(ddl), swsi.BaseStream);
                        swsi.Close();
                        swsi.Dispose();
                    }


                }
                Console.WriteLine("Complete");
                //Console.ReadKey();
            }
        }
        public static string CombinePath(string current, string path)
        {
            if (Path.IsPathRooted(path))
                return path;
            else
                return Path.Combine(current, path);
        }
    }
}
